#include "MemoryMenager.h"
#include "screen.h"
#include <iostream>
#include <fstream>
#include <conio.h>

using namespace std;

 #pragma warning(disable : 4244)
 #pragma warning(disable : 4996)

MemoryMenager::MemoryMenager(char *FN) : MemoryFileName(NULL)
{
	setName(FN);
	i_Alloc = 0;
	i_Free = 0;
	
}

MemoryMenager::~MemoryMenager()
{
	delete []MemoryFileName;
}

void MemoryMenager::setName(char *FN)
{
	delete []MemoryFileName;
	MemoryFileName = strdup(FN);

}

MemoryMenager::MemoryStruct MemoryMenager::getNextAction() 
{
	MemoryStruct temp;
	char str[2000];
    if (!MemoryFile.eof())
    {
	   MemoryFile>>str;
	   temp.Serial = (str[1] - '0')*10 + (str[2] - '0');
	   temp.MemoryAction = (str[3]=='+')?(MEM_ALLOCATE):( (str[3]=='-')?(MEM_FREEALL):(MEM_NOTVALID) );
	   if (temp.MemoryAction == MEM_ALLOCATE)
		   i_Alloc++;
	   else
		   i_Free++;
	}         
	else
	{
	   MemoryFile.close();
	   temp.Serial = -1;
	}

	return temp;
}

void MemoryMenager::Run()
{
MemoryMenager::MemoryStruct temp;
char ch=0;
int ActionIndex=0;
MemoryFile.open (MemoryFileName, ios::in); 
while ((temp = getNextAction()).Serial != -1)
{

	Draw(ActionIndex,0);

	if (kbhit())
		ch = getch();
	if (ch==27)
	{
		MemoryFile.close();
		break;
	}


	if (temp.MemoryAction == MEM_ALLOCATE)
		mem_Allocate(temp.Serial);

	if (temp.MemoryAction == MEM_FREEALL)
		mem_Free(temp.Serial);

	Draw(ActionIndex,7);


	Sleep(DELAY);
	ActionIndex++;


}


}

void MemoryMenager::Initialize()
{
	// Last item need to be -2
	for(int i=0;i<PHISICALMEMORY;i++)
		Memory[i] = i+1;

	pFreeSame = &Memory[0];
    
	for(int i=0;i<POINTERSIZE;i++)
		Pointer[i] = NULL;


}

void MemoryMenager::mem_Allocate(int Serial)
{

	Pointer[Serial]=pFreeSame;
		Draw(Serial,1);
	pFreeSame = &Memory[*pFreeSame];
		Draw(Serial,2);
	Memory[Pointer[Serial]-Memory] = -1;
		Draw(Serial,3);


}

void MemoryMenager::mem_Free(int Serial)
{

*Pointer[Serial] = pFreeSame - Memory; 
	Draw(Serial,4);
pFreeSame = Pointer[Serial];
	Draw(Serial,5);
Pointer[Serial] = NULL;
	Draw(Serial,6);

}

void MemoryMenager::Draw(int s,int stage) 
{
 if(stage==3)
 {
	cout<<"Block "<<s<<" Allocated"<<endl;
 }
 if(stage==6)
 {
	cout<<"Block "<<s<<" Deallocated"<<endl;
 
 }

}
